using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.IO;
using Microsoft.VisualBasic;
using System.Reflection;
using System.Collections;
using StockTrader.DAL.HoseAdapter.Lib;
using StockTrader.DAL.HoseAdapter.FileParser.Structure;
using System.Threading;

namespace StockTrader.DAL.HoseAdapter.FileParser
{
    public class FileEngineer
    {
        /// <summary>
        /// Read file which is indicate by xml file
        /// </summary>
        /// <param name="objType">FileStructure</param>
        /// <param name="Offset">Size</param>
        /// <returns></returns>
        public static ArrayList RetrieveFileInfo(DateTime selected, Type objType, long Offset)
        {
            string strXML = string.Empty;
            string RootFile = string.Empty;
            DataSet ds = null;
            BinaryReader br = null; FileStream fs = null;
            MemoryStream ms; StreamReader sr = null;
            ArrayList lstInfo = new ArrayList();

            if (null != objType)
            {
                strXML = AppDomain.CurrentDomain.BaseDirectory.Replace("bin\\Debug\\", "") + "Config\\FileDir.xml";
                ds = new DataSet();
                ds.ReadXml(strXML);
                if (ds.Tables.Count > 0)
                {
                    DataView dv = ds.Tables["FileConfig"].DefaultView;
                    dv.RowFilter = "ClassName='" + objType.Name + "'";
                    if (dv.Count > 0)
                    {
                        RootFile = ConfigurationManager.AppSettings["ROOT_" + dv[0]["RootPath"].ToString()].ToString();
                        if (dv[0]["RootPath"].ToString().Equals("PRS"))
                        {
                            RootFile += "\\BACKUP" + String.Format("{0:dd}", selected) + "\\";
                        }
                        if (RootFile == "")
                            RootFile = AppDomain.CurrentDomain.BaseDirectory;
                        RootFile = RootFile + "\\" + dv[0]["FilePath"].ToString();

                        if (RootFile.EndsWith("\\"))
                            RootFile = RootFile + selected.Date.ToString("yyyyMMdd") + "_data.dat";

                        string DesFile = dv[0]["KeyCode"].ToString() + (RootFile.Substring(RootFile.LastIndexOf("\\") + 1, RootFile.LastIndexOf(".") - RootFile.LastIndexOf("\\")) + "irs");
                        DesFile = AppDomain.CurrentDomain.BaseDirectory + @"" + DesFile;

                        if (File.Exists(RootFile))
                        {
                            bool isCopied = false;
                            while (!isCopied)
                            {
                                try
                                {
                                    CommonLib.SafeCopy(RootFile, DesFile);
                                    isCopied = true;
                                }
                                catch
                                {
                                    return lstInfo;
                                }
                            }
                        }
                        //Read copied data files
                        if (File.Exists(DesFile))
                        {
                            using (fs = new FileStream(DesFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            {
                                ms = new MemoryStream();
                                CommonLib.CopyStream(fs, ms);
                            }
                            if (Convert.ToInt32(dv[0]["FileType"]) == 0)
                            {
                                using (br = new BinaryReader(ms, Encoding.ASCII))
                                {
                                    if (null != br)
                                    {
                                        try
                                        {
                                            //Jum to preview position
                                            if (br.BaseStream.Length > Offset)
                                            {
                                                br.BaseStream.Position = Offset;
                                            }

                                            //Create instance of class
                                            while (br.PeekChar() != -1)
                                            {
                                                Object objClass = Activator.CreateInstance(objType);
                                                if (null != objClass)
                                                {
                                                    //Detect type of property
                                                    PropertyInfo[] lstProperties = objType.GetProperties();
                                                    foreach (PropertyInfo objProperty in lstProperties)
                                                    {
                                                        Object[] lstAttb = objProperty.GetCustomAttributes(true);
                                                        if (lstAttb.Length > 0)
                                                        {
                                                            //Get property length
                                                            FieldLengthAttribute objFileAttb = (FieldLengthAttribute)lstAttb[0];
                                                            //Set value to property
                                                            if (objProperty.PropertyType == typeof(String))
                                                            {
                                                                string strVal = string.Empty;
                                                                for (int i = 0; i < objFileAttb.FieldLength; i++)
                                                                    strVal += br.ReadChar();
                                                                objProperty.SetValue(objClass, strVal, null);
                                                            }
                                                            else if (objProperty.PropertyType == typeof(Int16))
                                                            {
                                                                byte[] btInt = br.ReadBytes(objFileAttb.FieldLength);
                                                                byte[] btOut = new byte[2];
                                                                for (int i = 0; i < btInt.Length; i++)
                                                                    btOut[2 - btInt.Length + i] = btInt[i];
                                                                Int16 intValue = System.BitConverter.ToInt16(btOut, 0);
                                                                objProperty.SetValue(objClass, intValue, null);
                                                            }
                                                            else if (objProperty.PropertyType == typeof(Int32))
                                                            {
                                                                byte[] btInt = br.ReadBytes(objFileAttb.FieldLength);
                                                                byte[] btOut = new byte[4];

                                                                //Int32 intValue1 = br.ReadInt32();
                                                                for (int i = 0; i < btInt.Length; i++)
                                                                    btOut[4 - btInt.Length + i] = btInt[i];

                                                                Int32 intValue = System.BitConverter.ToInt32(btOut, 0);
                                                                objProperty.SetValue(objClass, intValue, null);
                                                            }
                                                            else if (objProperty.PropertyType == typeof(Int64))
                                                            {
                                                                byte[] btInt = br.ReadBytes(objFileAttb.FieldLength);
                                                                //Int32 intValue = br.ReadInt32();
                                                                byte[] btOut = new byte[8];
                                                                for (int i = 0; i < btInt.Length; i++)
                                                                    btOut[8 - btInt.Length + i] = btInt[i];

                                                                Int64 intValue = System.BitConverter.ToInt64(btOut, 0);
                                                                objProperty.SetValue(objClass, intValue, null);
                                                            }
                                                            else if (objProperty.PropertyType == typeof(Double))
                                                            {
                                                                byte[] btInt = br.ReadBytes(objFileAttb.FieldLength);
                                                                byte[] btOut = new byte[8];
                                                                for (int i = 0; i < btInt.Length; i++)
                                                                    btOut[8 - btInt.Length + i] = btInt[i];
                                                                Double dblValue = System.BitConverter.ToDouble(btOut, 0);
                                                                objProperty.SetValue(objClass, dblValue, null);
                                                            }
                                                        }
                                                    }
                                                    lstInfo.Add(objClass);
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            return lstInfo;
                                        }
                                    }
                                }
                            }
                            else if (Convert.ToInt32(dv[0]["FileType"]) == 1)
                            {
                                DataSet rds = new DataSet();
                                rds.ReadXml(ms, XmlReadMode.ReadSchema);
                                if (rds.Tables.Count > 0)
                                {
                                    for (long i = Offset; i < rds.Tables[0].Rows.Count - 1; i++)
                                    {
                                        Object objClass = Activator.CreateInstance(objType);
                                        if (null != objClass)
                                        {
                                            PropertyInfo[] lstProperties = objType.GetProperties();
                                            foreach (PropertyInfo objProperty in lstProperties)
                                            {
                                                Object objVal = rds.Tables[0].Rows[(int)i][objProperty.Name].ToString();
                                                objProperty.SetValue(objClass, objVal, null);
                                            }
                                        }
                                        lstInfo.Add(objClass);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return lstInfo;
        }

        /// <summary>
        /// Read file which is indicate by xml file
        /// </summary>
        /// <param name="objType">FileStructure</param>
        /// <returns></returns>
        public static ArrayList RetrieveFileInfo(DateTime selected, Type objType)
        {
            return RetrieveFileInfo(selected, objType, 0);
        }
    }
    public sealed class CTCI_SUBDIR
    {
        public const string OrderCancellation = "1C";
        public const string OrderChange = "1D";
        public const string Advertisement = "1E";
        public const string OFPThroughDeal = "1F";
        public const string TFPThroughDeal = "1G";
        public const string NewConditionedOrder = "1I";
        public const string OrderConfirmation = "2B";
        public const string ConfirmOfOrderCancel = "2C";
        public const string ConfirmOfOrderChange = "2D";
        public const string DealConfirmation = "2E";
        public const string PutThroughAcknowledgment = "2F";
        public const string Reject = "2G";
        public const string CrossingDealConfirm = "2I";
        public const string PutThroughDealConfirmation = "2L";
        public const string PutThroughDealReply = "3B";
        public const string DealCancelRequest = "3C";
        public const string DealCancelReply = "3D";
    }
    public sealed class PRS_FILE
    {
        public const string SECURITY = "SER";
        public const string TOTAL_MARKET = "TOTALMKT";
        public const string PUT_AD = "PUTAD";
        public const string PUT_EXEC = "PUTEXEC";
        public const string PUT_DC = "PUTDC";
        public const string LE = "LE";
        public const string NEWLIST = "NEWLIST";
        public const string MARKET_STAT = "MRKSTS";
        public const string DELIST = "DELLIST";
        public const string FROOM = "FROOM";
    }
}

